package databaseComm;

import java.util.Date;
import java.util.List;

import results.IncorrectProblemStatistic;
import results.Result;

import equations.MathFactsCategory;
import equations.Problem;

import accounts.Account;

/**
 * This interface specifies an API that will interact with the database. 
 * This will be stubbed until an actual implementation is available.
 * @author stewarte
 *
 */
public interface DatabaseDriverInterface {
	
	/**
	 * Connects to the database at the given address
	 * @param address
	 * @return
	 */
	boolean connectToDatabase(String address);
	
	/**
	 * This function will poll the database to see whether or not a user is authentic.
	 * If user is not authentic, function will return an empty string,
	 * 
	 * Otherwise, if user is valid, this method will return a 
	 * @param username
	 * @param password
	 * @return
	 */
	String authenticateLogin(String username, String password);
	
	/**
	 * This function will create a new account. The first argument,
	 * creator, will be used to authenticate whether the creator has
	 * proper clearance to create an account. Account toBeCreated, is the account
	 * we are going to create and add to the database.
	 * 
	 * @return isSuccessful
	 */
	boolean createAccount(Account creator, Account toBeCreated);
	
	/**
	 * This function will delete an account from the database. First arg,
	 * deleter, will be checked to see if delete clearance is available (i.e. only an
	 * admin can delete an account). Account toBeDeleted contains the information of the
	 * account to be deleted.
	 * 
	 * @return isSuccessful
	 */
	boolean deleteAccount(Account deleter, Account toBeDeleted);
	
	/**
	 * This method will change the password of toBeChanged to newPassword, if changer
	 * has proper authentication to change an account passwords (i.e., if changer is an
	 * admin).
	 * @param changer
	 * @param toBeChanged
	 * @param newPassword
	 * @return
	 */
	boolean changePassword(Account changer, Account toBeChanged, String newPassword);
	
	/**
	 * Retrieves the password, checks to see if retriever is authorized to 
	 * retrieve passwords (i.e. Admin or Instructor). Returns "NOT_IN_DB"
	 * if unable to retrieve password because username not in database. If unable,
	 * to find a password for any other reason, returns an empty string.
	 * 
	 * @param retriever
	 * @param username
	 * @return password
	 */
	String retrievePassword(Account retriever, String username);
	
	/**
	 * Creates an equation for a given math facts category and set number.
	 * 
	 * @param mfc
	 * @param equation
	 * @param solution
	 * @return wasSuccessful
	 */
	boolean createEquation(MathFactsCategory mfc, String equation, String solution, int set);
	
	/**
	 * Deletes an equation with the given category, equation and set.
	 * @param mfc
	 * @param equation
	 * @param set
	 * @return wasSuccessful
	 */ 
	boolean deleteEquation(MathFactsCategory mfc, String equation, int set);
	
	/**
	 * Get's all the equations associated with a specific category (i.e. Multiplication I).
	 * This will return the MathFactsCategory. The MathFactsCategory needs to be populated
	 * with sets of equations. These are stored as arraylists of problems. The
	 * MathFactsCategory is supplied directly to the quizzer interface, which simply
	 * iterates through each list of equations.
	 * @return MathFactsCategory
	 */
	MathFactsCategory getAllEquationsForCategory(String categoryName);
	
	/**
	 * Store the result of the session into the database
	 * @return
	 */
	boolean addResult(Result r);
	
	/**
	 * Gets all the results for a given category and user
	 * @param mfc
	 * @return
	 */
	List<Result> getAllResultsForCategory(MathFactsCategory mfc, String username);
	
	/**
	 * Gets all the results for for a given user, irregardless of category
	 * @param mfc
	 * @return
	 */
	List<Result> getsAllResults( String username);
	
	/**
	 * Passes in the problem that is incorrect to the database. Checks if the problem is already in the database
	 * for the user. If it is, increment the count wrong. If not, add a new entry with the given problem
	 * for the given user.
	 * @param p
	 * @return
	 */
	boolean addIncorrectEquationResult(Problem p, String username);
	
	/**
	 * Gets the list of incorrect problems and the stats for each incorrect problem, IncorrectProblemStatistic
	 * wraps problem and has a count.
	 * @param username
	 * @return
	 */
	List<IncorrectProblemStatistic> getIncorrectProblemsStatistics(String username);
	
	
	
}
